// g++ rtsql.cpp demo_rtsql_cpp.cpp -lsqlite3 -std=c++11 -o demo

#include "rtsql.h"
#include <stdlib.h>

SQLite_Bind_CallBack3(Func_Insert_tb1, Node_Insert_tb1, int, string, string)
SQLite_Bind_CallBack1(Func_Delete_tb1, Node_Delete_tb1, int)

int main(int argc, char* argv[]){
    Sqlite3DB *db = new Sqlite3DB();
    try{
        // 打开数据库
        db->open("../test.db");

        // 加密数据库
        if(argc > 1){
            if(!strcmp(argv[1], "clear")){
                char strCipher[20] = {0};
                char strCipher_new[20] = {0};
                printf("Please Input the Origin Key -> ");
                scanf("%s", strCipher);
                printf("Please Input a New Key -> ");
                scanf("%s", strCipher_new);
                if(strcmp(strCipher_new, "null"))  // 更改密码
                    db->setkey(strCipher, strCipher_new);
                else                               // 清除密码
                    db->setkey(strCipher, "");
            }
            else if(!strcmp(argv[1], "encrypt")){
                // 给未加密数据库添加密码
                char strCipher[20] = {0};
                printf("Please Input the New Key -> ");
                scanf("%s", strCipher);
                db->setkey("", strCipher);
            }
        }

        // 验证密码
        char strCipher[20] = {0};
        printf("Please Input the Cipher -> ");  scanf("%s", strCipher);
        if(strcmp(strCipher, "null"))
            db->unlock(strCipher);

        // 指定操作表
        db->assign_table("tb1");

        // 插入单条数据
        db->exec("insert into tb1 values (1024,'test','running test.');", nullptr, nullptr);

        // 查询数据库
        db->show("content='test'");
        // db->exec("select (no) from tb1 where content='abc';", Sqlite3DB::callback_show_table, NULL);

        // 插入新数据
        struct Node_Insert_tb1 ins_values[] = {
            {3670, "a", "aaa"},
            {3671, "b", "bbb"},
            {3672, "c", "ccc"},
            {3673, "d", "ddd"},
            {3674, "r", "rrr"}
        };
        SQLite3DB_Batch(db, "insert into tb1 values (?, ?, ?);", ins_values, Func_Insert_tb1, 3);

        // 删除行
        struct Node_Delete_tb1 del_values[] = {
            {3670}
        };
        SQLite3DB_Batch(db, "delete from tb1 where no=?;", del_values, Func_Delete_tb1, 1);

        // 返回数据
        if(db->select("no=5") < 0){
            _print("Stop at select.");
            goto trouble;
        }

        // 显示查询
        char* sel = db->select("content='b'", 0, 2);
        _print("the description is : %s", sel);
    }
    catch(Sqlite3Except_Select& e){
        printf("%s\n", e.what());
    }
    catch(Sqlite3Except& e){
        printf("%s\n", e.what());
        db->error();
    }
    catch(const char* e){
        printf(e);  printf("\n");
        db->error();
    }
    delete db;
    return 0;

trouble:
    db->error();
    delete db;
    _print("Trouble Occured.");
    return -1;
}

/*
struct SQL_Bind_Node{ \
    int p0;
    string p1;
    string p2; };

void* bind_callback(void* params, int index, BINDMAP_TYPE* type){
    SQL_Bind_Node *node = (SQL_Bind_Node*)params;
    if(0 == index){
        *type = SQLITE_BIND_INT;
        return (void*)(&node->p0);
    }else if(1 == index){
        *type = SQLITE_BIND_TEXT;
        return (void*)(&node->p1);
    }else if(2 == index){
        *type = SQLITE_BIND_TEXT;
        return (void*)(&node->p2);
    }else{
        return nullptr;
    }
}
*/